import java.util.Arrays;

public class MyArrayList {
    int[] item ;//设立数组
    int UseSize;//用来表示顺序表目前的存储最后一个元素的位置
    public static final int CAPACITY = 10;//默认数组容量为10

    //构造方法：默认容量
    public MyArrayList(){
        this.item = new int[CAPACITY];
    }

    //构造方法重写：指定容量
    public MyArrayList(int initcapacity){
        this.item = new int[initcapacity];
    }


    // 打印顺序表，注意：该方法并不是顺序表中的方法，为了方便看测试结果给出的
    //实质：遍历数组
    public void display (){
        //这里遍历到存储的最后一个元素位置 即 UseSize ,而非 item.length
        for (int i = 0; i < this.UseSize; i++) {
            System.out.print(item[i] + " ");
        }
    }


    // 新增元素,默认在数组最后新增
    //小心越界情况
    public void add(int data){
        //可能越界故在下面方法写一个判断是否数组容量已满的情况
        if(IsFull()){
            this.item = Arrays.copyOf(this.item,2*(this.item.length));
        }
        this.item[this.UseSize] = data;
        this.UseSize++;
    }

    //越界处理：判断是否数组容量已满的情况
    public boolean IsFull(){
        if(this.UseSize == this.item.length){
            return true;
        }
        return false;
    }

    // 在 pos 位置新增元素
    public void add(int pos,int data){
        //注意判断pos位置是否合法
        if(pos < 0 || pos > this.UseSize){
            //System.out.println("位置不合法！");
            //return;
            //可以用抛出异常来解决
            throw new PosOutOfBoundException(pos + " 位置不合法");
        }
        //注意越界
        if(IsFull()){
            this.item = Arrays.copyOf(this.item,2*(this.item.length));
        }
        //注意 要先挪动包含pos在内后面的所有数据！
        //切记：从后往前挪！！
        for (int i = this.UseSize-1; i >= pos; i++) {
            this.item[i+1] = this.item[i];
        }
        this.item[pos] = data;
        this.UseSize++;
    }


    // 判定是否包含某个元素
    // 返回类型：Boolean
    //注意：如果是引用类型让你判断呢？
    //此时就要用equals->返回true or false(注意区别：compareTo ->返回大于 等于 小于 0 数字）
    public boolean contains(int toFind){
        for(int i = 0 ;i < this.UseSize;i++){
            if(this.item[i] == toFind){
                return true;
            }
        }
        return false;
    }

    // 查找某个元素对应的位置
    public int indexOf(int toFind) {
        for (int i = 0; i < this.UseSize; i++) {
            if(this.item[i] == toFind){
                return i;
            }
        }
        return -1;
    }


    // 获取 pos 位置的元素
    public int get(int pos) {
        //先判断pos位置是否合法 这里设置一个方法 CheckPos
        CheckPos(pos);
        return this.item[pos];
        }


    // 给 pos 位置的元素设为 value
    public void set(int pos, int value) {
        //同上，先判断pos位置是否合法
        CheckPos(pos);
        this.item[pos] = value;
    }


    //判单pos的合法性
    public void CheckPos(int pos){
        if(pos<0 || pos >= this.UseSize){
            throw new PosOutOfBoundException(pos + " 位置不合法！");
        }
    }
    //删除第一次出现的数据元素value
    public void remove(int toRemove) {
        //先查看是否有这个元素在顺序表中，并得到这个元素位置
        //可以运用我们上面已经写的方法indexOf
        int index = this.indexOf(toRemove);
        if(index == -1){
            System.out.println("没有这个数据!");
            return;//注意返回！
        }
        //从前往后移动数组的元素，往前覆盖前一个元素
        //注意！这里index接收的是元素下标，而toRemove是具体的数据
        for (int i = index; i < this.UseSize-1; i++) {
            this.item[i] = this.item[i+1];
        }

        //引用类型加一步：this.item[UseSize]=null; 即最后一个对象指向要设为空
        this.UseSize--;
    }
    // 获取顺序表长度
    public int size() {
        return this.UseSize; }
    // 清空顺序表
    public void clear() {
        //引用类型多一部：删掉的对象指向要设为空null
        /*
            for (int i = 0; i < this.UseSize; i++) {
            this.item[i]=null;
        }  */
        this.UseSize = 0;
    }
}
